package com.gk.panda.apis.patrol.servicr.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gk.panda.apis.dto.RealtimeShootSaveDto;
import com.gk.panda.apis.excelobject.ExReportDTO;
import com.gk.panda.apis.patrol.commons.DateUtils;
import com.gk.panda.apis.patrol.commons.EasypoiExcelUtils;
import com.gk.panda.apis.patrol.commons.StateEnum;
import com.gk.panda.apis.patrol.mapper.PatrolMapper;
import com.gk.panda.apis.patrol.mapper.ReportMapper;
import com.gk.panda.apis.patrol.servicr.PatrolService;
import com.gk.panda.apis.patrol.servicr.ReportResourceService;
import com.gk.panda.apis.patrol.servicr.ReportService;
import com.gk.panda.apis.service.RealtimeShootService;
import com.gk.panda.commons.exception.ServerException;
import com.gk.panda.commons.result.Result;
import com.gk.panda.commons.util.UserUtil;
import com.gk.panda.pojo.patrol.dto.*;
import com.gk.panda.pojo.patrol.entity.LocationInfoEntity;
import com.gk.panda.pojo.patrol.entity.PatrolEntity;
import com.gk.panda.pojo.patrol.entity.ReportEntity;
import com.gk.panda.pojo.patrol.entity.ReportResourceEntity;
import com.gk.panda.pojo.patrol.request.LocationRequest;
import com.gk.panda.pojo.patrol.request.PageReportRequest;
import com.gk.panda.pojo.patrol.request.SaveReportRequest;
import com.gk.panda.pojo.patrol.request.UpdateReportRequest;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author：xxz
 * @Create: 2022/11/1 15:57
 */
@Service
public class ReportServiceImpl extends ServiceImpl<ReportMapper, ReportEntity> implements ReportService {
    @Autowired
    private PatrolService patrolService;

    @Autowired
    private PatrolMapper patrolMapper;
    @Autowired
    private ReportResourceService reportResourceService;
    @Autowired
    private DateUtils dateUtils;
    @Autowired
    private LocationInfoServiceImpl locationInfoService;

    @Autowired
    private RealtimeShootService realtimeShootService;

    @Override
    public List<Long> getIdsByReport(Long patrolId) {
        List<Long> userIds;
        List<ReportEntity> list = this.baseMapper.selectList(
                new LambdaQueryWrapper<ReportEntity>().eq(ReportEntity::getPatrolId, patrolId)
        );
        userIds = list.stream().map(ReportEntity::getId).distinct().collect(Collectors.toList());
        return userIds;
    }


    @Override
    public void export(HttpServletResponse response, PageReportRequest request) {
        request.setPageSize(-1);
        Page<ReportPageDTO> pageDate = this.queryPage(request);
        List<ExReportDTO> exPatrolDTOS = BeanUtil.copyToList(pageDate.getRecords(), ExReportDTO.class);
        try {
            EasypoiExcelUtils.exportExcel(exPatrolDTOS, null, "sheet1", ExReportDTO.class, "巡护事件信息表.xls", response);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("导出巡护事件信息失败");
        }
    }

    @Override
    public Long countReport(String name, String type, DateTime startTime, DateTime endTime) {
        return this.baseMapper.countReport(name, type, startTime, endTime);
    }

    @Override
    public ReportSumDTO countData(PageReportRequest request) {
        ReportSumDTO reportSumDTO = new ReportSumDTO();
        // 解析机构
        if (!StringUtils.isEmpty(request.getTotalOrgId())) {
            request.setOrgIds(Arrays.asList(request.getTotalOrgId().split(",")));
        }
        // 解析巡护类型
        if (!StringUtils.isEmpty(request.getPatrolType())) {
            request.setPatrolTypes(Arrays.asList(request.getPatrolType().split(",")));
        }
        // 解析事件类型
        if (!StringUtils.isEmpty(request.getReportType())) {
            request.setReportTypes(Arrays.asList(request.getReportType().split(",")));
        }
        //查询样线巡护事件上报数
        reportSumDTO.setTransectCount(
                patrolService.getCountPatrol(StateEnum.PATROL_TYPE.TRANSECT.getType(), request));
        reportSumDTO.setDailyCount(
                patrolService.getCountPatrol(StateEnum.PATROL_TYPE.DAILY.getType(), request)
        );
        return reportSumDTO;
    }

    @Override
    public UpdateDetailDTO updateDetail(Long id) {
        List<UrlDTO> picture = reportResourceService.getUrlByReportId(StateEnum.RESOURCE_TYPE.PICTURE.getType(), id);
        List<UrlDTO> video = reportResourceService.getUrlByReportId(StateEnum.RESOURCE_TYPE.VIDEO.getType(), id);
        ReportEntity reportEntity = this.getById(id);
        UpdateDetailDTO updateDetailDTO = new UpdateDetailDTO();
        if (reportEntity != null) {
            BeanUtil.copyProperties(reportEntity, updateDetailDTO);
        }
        if (!CollectionUtils.isEmpty(picture)) {
            updateDetailDTO.setPicture(picture);
        }
        if (!CollectionUtils.isEmpty(video)) {
            updateDetailDTO.setVideo(video);
        }
        return updateDetailDTO;
    }

    @Override
    public Double countRouteSum(String name, String type) {
        return baseMapper.countRouteSum(name, type);
    }


    @Override
    public Page<ReportPageDTO> queryPage(PageReportRequest request) {

        //分页
        Page<ReportPageDTO> page = new Page<>(request.getPageNo(), request.getPageSize());
        // 解析机构
        if (!StringUtils.isEmpty(request.getTotalOrgId())) {
            request.setOrgIds(Arrays.asList(request.getTotalOrgId().split(",")));
        }
        // 解析巡护类型
        if (!StringUtils.isEmpty(request.getPatrolType())) {
            request.setPatrolTypes(Arrays.asList(request.getPatrolType().split(",")));
        }
        // 解析事件类型
        if (!StringUtils.isEmpty(request.getReportType())) {
            request.setReportTypes(Arrays.asList(request.getReportType().split(",")));
        }
        Page<ReportPageDTO> pageDate = this.baseMapper.queryPage(page, request);

        pageDate.getRecords().forEach(
                i -> {
                    if (!StringUtils.isEmpty(i.getReportType())) {
                        i.setReportTypeDes(StateEnum.REPORT_TYPE.getEnum(i.getReportType()).getDesc());
                    }
                    if (!StringUtils.isEmpty(i.getPatrolType())) {
                        i.setPatrolTypeDes(StateEnum.PATROL_TYPE.getEnum(i.getPatrolType()).getDesc());
                    }
                    List<UrlDTO> picture = reportResourceService.getUrlByReportId(StateEnum.RESOURCE_TYPE.PICTURE.getType(), i.getReportId());
                    List<UrlDTO> video = reportResourceService.getUrlByReportId(StateEnum.RESOURCE_TYPE.VIDEO.getType(), i.getReportId());
                    //设置资源地址
                    if (!CollectionUtils.isEmpty(picture)) {
                        i.setPicture(picture);

                    }
                    if (!CollectionUtils.isEmpty(video)) {
                        i.setVideo(video);
                    }
                }

        );


        return pageDate;
    }

    @Override
    public ReportDetailDTO detail(Long reportId) {
        ReportDetailDTO reportDetailDTO = this.baseMapper.detail(reportId);
        //设置总时长
        if (reportDetailDTO.getWhenTime() != null) {
            reportDetailDTO.setDateSum(dateUtils.msToTime(reportDetailDTO.getWhenTime()));
        }
        //设置巡护人员
        if (StringUtils.isEmpty(reportDetailDTO.getOthersPeople())) {
            reportDetailDTO.setJoin(reportDetailDTO.getPeople());

        } else if (StringUtils.isEmpty(reportDetailDTO.getPeople())) {
            reportDetailDTO.setJoin(reportDetailDTO.getOthersPeople());

        } else if ((!StringUtils.isEmpty(reportDetailDTO.getPeople()))
                && (!StringUtils.isEmpty(reportDetailDTO.getPeople()))) {
            reportDetailDTO.setJoin(reportDetailDTO.getPeople() + "；" + reportDetailDTO.getOthersPeople());

        }
        // 总参与人数
        String[] split = reportDetailDTO.getJoin().split("；");
        reportDetailDTO.setNumberOf(split.length);
        //设置时间段
        if (StringUtils.isEmpty(reportDetailDTO.getEndTime())) {
            reportDetailDTO.setPatrolDate(dateUtils.sub(
                    reportDetailDTO.getStartTime(), null, "~"));
        } else {
            reportDetailDTO.setPatrolDate(dateUtils.sub(
                    reportDetailDTO.getStartTime(), reportDetailDTO.getEndTime(), "~"));
        }
        //设置巡护路线图经纬度
        List<PointDTO> pointDTOS = locationInfoService.locationPoint(reportDetailDTO.getPatrolId());
        if (!CollectionUtils.isEmpty(pointDTOS)) {
            reportDetailDTO.setPointList(pointDTOS);
        }
        //设置巡护类型
        reportDetailDTO.setPatrolTypeName(StateEnum.PATROL_TYPE.getEnum(reportDetailDTO.getPatrolType()).getDesc());
        //设置巡护状态
        reportDetailDTO.setStateDes(StateEnum.PATROL_STATE.getEnum(reportDetailDTO.getState()).getDesc());
        List<UrlDTO> picture = reportResourceService.getUrlByReportId(StateEnum.RESOURCE_TYPE.PICTURE.getType(), reportDetailDTO.getReportId());
        List<UrlDTO> video = reportResourceService.getUrlByReportId(StateEnum.RESOURCE_TYPE.VIDEO.getType(), reportDetailDTO.getReportId());
        //设置资源地址
        if (!CollectionUtils.isEmpty(picture)) {
            reportDetailDTO.setPicture(picture);

        }
        if (!CollectionUtils.isEmpty(video)) {
            reportDetailDTO.setVideo(video);
        }
        return reportDetailDTO;
    }

    @Override
    public Result<?> update(UpdateReportRequest request) {
        String name =
                UserUtil.getCurrentUser(); //获取当前对象
        ReportEntity reportEntity = new ReportEntity();
        BeanUtil.copyProperties(request, reportEntity);
        boolean flag = this.updateById(reportEntity);  //修改事件信息
        Date date = new Date();
        List<ReportResourceEntity> reportResource = new ArrayList<>();
        //先删除该事件下的所有 资源，然后再重新添加
        final List<Long> ids = reportResourceService.ids(request.getId());
        if (!CollectionUtils.isEmpty(ids)) {
            boolean b = reportResourceService.removeByIds(ids);
            if (!b) {
                return Result.write(StateEnum.RESULT_CODE.ERROR.getCode(), "移除旧数据异常");
            }
        }
        //图片
        for (String picture : request.getPicture()) {
            ReportResourceEntity reportResourceEntity = new ReportResourceEntity(
                    reportEntity.getId(), request.getPatrolId(), StateEnum.RESOURCE_TYPE.PICTURE.getType(), picture, date, name);
            reportResource.add(reportResourceEntity);
        }
        //视频
        for (String video : request.getVideo()) {
            ReportResourceEntity reportResourceEntity = new ReportResourceEntity(
                    reportEntity.getId(), request.getPatrolId(), StateEnum.RESOURCE_TYPE.VIDEO.getType(), video, date, name);
            reportResource.add(reportResourceEntity);
        }
        // 巡护人员修改
        PatrolEntity byId = patrolMapper.getById(request.getPatrolId());
        //其他人员 、巡护人员都为空报错
        if (StringUtils.isEmpty(request.getPatrolNames()) && StringUtils.isEmpty(request.getOthersPatrolNames())) {
            return Result.write(StateEnum.RESULT_CODE.ERROR.getCode(), "填写巡护人员错误!");
        }
        if (!StringUtils.isEmpty(request.getPatrolNames())) {
            byId.setPeople(request.getPatrolNames());
        }
        if (!StringUtils.isEmpty(request.getOthersPatrolNames())) {
            byId.setOthersPeople(request.getOthersPatrolNames());
        }
        if (!StringUtils.isEmpty(request.getUnits())) {
            byId.setUnit(request.getUnits());
        }
        if (!StringUtils.isEmpty(request.getName())) {
            byId.setName(request.getName());
        }
        if (!StringUtils.isEmpty(request.getTheme())) {
            byId.setTheme(request.getTheme());
        }
        byId.setModifyTime(date);
//
        byId.setModifyBy(UserUtil.getCurrentUser());
        patrolService.updateById(byId);
        boolean resource = reportResourceService.saveBatch(reportResource, 3);
        if (resource) {
            return Result.ok("修改成功事件信息");
        }
        if (flag) {
            return Result.ok("修改成功事件信息");
        }

        return Result.write(StateEnum.RESULT_CODE.ERROR.getCode(), "修改失败");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> remove(Long id) {
        // 删除事件c
        Boolean flag = this.removeById(id);
        // 删除事件下的资源，如果存在
        List<ReportResourceEntity> list = reportResourceService.list(
                new LambdaQueryWrapper<ReportResourceEntity>().eq(ReportResourceEntity::getReportId, id));
        if (!CollectionUtils.isEmpty(list)) {
            List<Long> ids = list.stream().map(ReportResourceEntity::getId).collect(Collectors.toList());
            flag = reportResourceService.removeByIds(ids);
        }
        // 删除位置信息
        locationInfoService.remove(new LambdaQueryWrapper<LocationInfoEntity>().eq(LocationInfoEntity::getReportId, id));
        if (flag) {
            return Result.ok("ok");
        }
        return Result.write(StateEnum.RESULT_CODE.ERROR.getCode(), "删除失败请稍后再试");
    }

    @Override
    public DetailListDTO detailList(Long id) {
        try {
            //巡护
            DetailListDTO detailListDTO = patrolService.getPatrolById(id);
            if (detailListDTO == null) {
                return new DetailListDTO();
            }
            detailListDTO.setPatrolName(StateEnum.PATROL_TYPE.getEnum(detailListDTO.getType()).getDesc());
            //设置时间段
            if (StringUtils.isEmpty(detailListDTO.getEndTime())) {
                String startDate = DateUtil.format(detailListDTO.getStartTime(), "yyyy.MM.dd HH:mm");
                detailListDTO.setPatrolDate(
                        startDate + "~");
            } else {
                detailListDTO.setPatrolDate(dateUtils.sub(
                        detailListDTO.getStartTime(), detailListDTO.getEndTime(), "~"));
            }

            //总时长
            if (!StringUtils.isEmpty(detailListDTO.getWhenTime())) {
                detailListDTO.setDateSum(DateUtils.msHour3(detailListDTO.getWhenTime()));
            }
            if (!StringUtils.isEmpty(detailListDTO.getPeople())) {
                detailListDTO.setPeopleNames(Arrays.asList(detailListDTO.getPeople().split("；")));


            }

            //设置参加人员
//        String people = detailListDTO.getPeople().replace("；", " ");
            if (StringUtils.isEmpty(detailListDTO.getOthersPeople())) {
                detailListDTO.setJoin(detailListDTO.getPeople());

            } else if (StringUtils.isEmpty(detailListDTO.getPeople())) {
//            String other = detailListDTO.getOthersPeople().replace("；", " ");
                detailListDTO.setJoin(detailListDTO.getOthersPeople());

            } else if ((!StringUtils.isEmpty(detailListDTO.getPeople()))
                    && (!StringUtils.isEmpty(detailListDTO.getPeople()))) {
                detailListDTO.setJoin(detailListDTO.getPeople() + "；" + detailListDTO.getOthersPeople());

            }
            // 总参与人数
            String[] split = detailListDTO.getJoin().split("；");
            detailListDTO.setNumberOf(split.length);
            //----------// 事件信息
            detailListDTO.setReportDTOList(pageReport(id));
            //设置 事件坐标
            List<PointDTO> pointDTOS = locationInfoService.locationPoint(id);
            if (!CollectionUtils.isEmpty(pointDTOS)) {
                detailListDTO.setPointList(pointDTOS);
            }
            detailListDTO.setStateDesc(StateEnum.PATROL_STATE.getEnum(detailListDTO.getState()).getDesc());
            return detailListDTO;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServerException("操作失败请稍后再试");
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> saveReport(SaveReportRequest request) {
        //查询巡护信息
        PatrolEntity byId = patrolMapper.getById(request.getPatrolId());
        // 已经删除不做任何操作
        if (byId.getDelFlag().equals(-1)) {
            return Result.ok("事件添加成功");
        }

        String name = UserUtil.getCurrentUser(); //获取当前对象
        int orgId = UserUtil.getCurrentUserOrgId();
        String abbr = UserUtil.getCurrentUserOrgAbbr();
        ReportEntity reportEntity = new ReportEntity();
        //事件编号
        String num = patrolService.createOrderNum(abbr + "SJ", "yyyyMMdd");
        reportEntity.setReportNum(num);
        if (NumberUtil.isNumber(request.getTemperature())) {
            request.setTemperature(request.getTemperature());
        } else {
            request.setTemperature("");
        }

        if (NumberUtil.isNumber(request.getHumidity())) {
            request.setHumidity(request.getHumidity());
        } else {
            request.setHumidity("");
        }
        if (NumberUtil.isNumber(request.getElevation())) {
            request.setElevation(request.getElevation());
        } else {
            request.setElevation("");
        }
        BeanUtils.copyProperties(request, reportEntity);
        // 时间使用前端提交时间
        Date date = request.getCreateTime();
        reportEntity.setCreateBy(name);


        //存入实时抓拍
        if (request.getType().equals(StateEnum.REPORT_TYPE.INSTANT.getType())) {
            //将图片放入
            if (!CollectionUtils.isEmpty(request.getPicture())) {

                for (String picture : request.getPicture()) {
                    RealtimeShootSaveDto realtimeShootSaveDtoP = new RealtimeShootSaveDto(
                            picture, date, "手持终端", num, "", request.getDescription(), 2, request.getLongitude(), request.getLatitude(), orgId, name
                    );
                    realtimeShootService.addRealTimeShoot(realtimeShootSaveDtoP);//保存进实时表
                }


            }

            //存入视频
            if (!CollectionUtils.isEmpty(request.getVideo())) {

                for (String video : request.getVideo()) {
                    RealtimeShootSaveDto realtimeShootSaveDtoV = new RealtimeShootSaveDto(
                            video, date, "手持终端", num, "", request.getDescription(), 2, request.getLongitude(), request.getLatitude(), orgId, name
                    );
                    realtimeShootService.addRealTimeShoot(realtimeShootSaveDtoV);//保存进实时表
                }

            }


        }


        boolean save = this.save(reportEntity);
        List<ReportResourceEntity> reportResource = new ArrayList<>();
        //图片
        for (String picture : request.getPicture()) {
            ReportResourceEntity reportResourceEntity = new ReportResourceEntity(
                    reportEntity.getId(), reportEntity.getPatrolId(), StateEnum.RESOURCE_TYPE.PICTURE.getType(), picture, date, name);
            reportResource.add(reportResourceEntity);
        }
        //视频
        for (String video : request.getVideo()) {
            ReportResourceEntity reportResourceEntity = new ReportResourceEntity(
                    reportEntity.getId(), reportEntity.getPatrolId(), StateEnum.RESOURCE_TYPE.VIDEO.getType(), video, date, name);
            reportResource.add(reportResourceEntity);
        }
        if (!CollectionUtils.isEmpty(reportResource)) {
            boolean resource = reportResourceService.saveBatch(reportResource);

        }

        // 添加事件位置到位置信息表中
        LocationRequest locationRequest = new LocationRequest();
        locationRequest.setLon(request.getLongitude());
        locationRequest.setLat(request.getLatitude());
        locationRequest.setPatrolId(request.getPatrolId());
        locationRequest.setIsEvent(1);
        locationRequest.setReportId(reportEntity.getId());
        locationRequest.setCreateTime(date);
        patrolService.location(locationRequest);
        //其他人员 、巡护人员都为空报错
        if (StringUtils.isEmpty(request.getPatrolNames()) && StringUtils.isEmpty(request.getOthersPatrolNames())) {
            return Result.write(StateEnum.RESULT_CODE.ERROR.getCode(), "填写巡护人员错误!");
        }

        // 巡护人员修改
        if (!StringUtils.isEmpty(request.getPatrolNames())) {
            byId.setPeople(request.getPatrolNames());
        }
        if (!StringUtils.isEmpty(request.getOthersPatrolNames())) {
            byId.setOthersPeople(request.getOthersPatrolNames());
        }
        if (!StringUtils.isEmpty(request.getUnits())) {
            byId.setUnit(request.getUnits());
        }
        if (!StringUtils.isEmpty(request.getName())) {
            byId.setName(request.getName());
        }
        if (!StringUtils.isEmpty(request.getTheme())) {
            byId.setTheme(request.getTheme());
        }
        byId.setModifyTime(date);
        byId.setModifyBy(UserUtil.getCurrentUser());
        patrolService.updateById(byId);

        if (save) {
            return Result.ok("事件添加成功");
        }
        return Result.write(StateEnum.RESULT_CODE.ERROR.getCode(), "添加事件失败");
    }

    @Override
    public List<ReportDTO> pageReport(Long patrolId) {
        //List<Long> ReportIds = getIdsByReport(patrolId);
        List<ReportDTO> pageData = new ArrayList<>();
//        if (CollectionUtils.isEmpty(ReportIds)) {
//            return pageData;
//        }
        pageData = this.baseMapper.queryList(patrolId);
        pageData.forEach(
                item -> {
                    item.setTypeName(StateEnum.REPORT_TYPE.getEnum(item.getType()).getDesc());
                    item.setPicture(
                            reportResourceService.getUrlByReportId(StateEnum.RESOURCE_TYPE.PICTURE.getType(), item.getId()));
                    item.setVideo(reportResourceService.getUrlByReportId(StateEnum.RESOURCE_TYPE.VIDEO.getType(), item.getId()));
                }
        );
        return pageData;
    }

}
